package didi.hcp.provider.aspect;

import didi.hcp.provider.annotation.NeedUser;
import didi.hcp.provider.service.INeedUser;
import org.apache.dubbo.rpc.RpcContext;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

/**                                                                                ____________________
     _                _                                                           < 神兽护体，永无bug! >
    | |__  _   _  ___| |__   ___ _ __   __ _ _ __   ___ _ __   __ _                --------------------
   | '_ \| | | |/ __| '_ \ / _ \ '_ \ / _` | '_ \ / _ \ '_ \ / _` |                      \   ^__^
  | | | | |_| | (__| | | |  __/ | | | (_| | |_) |  __/ | | | (_| |                        \  (oo)\_______
 |_| |_|\__,_|\___|_| |_|\___|_| |_|\__, | .__/ \___|_| |_|\__, |                            (__)\       )\/\
                                   |___/|_|                |___/                                ||----w |
                                                                                                ||     ||
 * @author huchengpeng
 * @date 2021/11/4 4:59 下午
 * @version 切面，给需要获取获取用户登录信息的方法注入用户信息
 * @Description 
 */
@Aspect
@Component
public class GetUserAspect {

    @Pointcut("@annotation(didi.hcp.provider.annotation.NeedUser)")
    public void pointcut() {
        // do nothing
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Object result = null;
        Object curObj = point.getThis();
        if(curObj instanceof INeedUser){
            INeedUser needUser = (INeedUser) curObj;
            // 获取上下文的
            String attachment = RpcContext.getContext().getAttachment("name");
            // 获取已经保存的
            Object o = needUser.get();
            System.out.println("around " +o);
            if(o == null){
                // 当前没保存才会设置
                needUser.set(attachment);
            }
            // 执行方法
            result = point.proceed();
            Signature signature = point.getSignature();
            MethodSignature methodSignature = (MethodSignature) signature;
            NeedUser annotation = methodSignature.getMethod().getAnnotation(NeedUser.class);
            boolean selfRemove = annotation.selfRemove();
            if(!selfRemove){
                // 内存回收
                needUser.remove();
            }
        }
        return result;
    }

    @AfterThrowing("pointcut()")
    public void afterThrowing(JoinPoint jp){
        Object curObj = jp.getThis();
        if(curObj instanceof INeedUser){
            INeedUser needUser = (INeedUser) curObj;
            // 内存回收
            needUser.remove();
        }
    }
}